<template>
  <div>
    <router-link :to="link">查看文档</router-link>
    <div class="item">
      <label>请求地址：</label>
      <span>{{ baseUrl }}{{ url }}{{ paramData }}</span>
    </div>

    <div class="item">
      <label>请求方式：</label>
      <span>{{ methodType }}</span>
    </div>

    <div class="item" v-if="isToken">
      <label>accessToken：</label>
      <input
        class="input"
        type="text"
        placeholder="调用接口凭证"
        v-model="accessToken"
      />
    </div>

    <div class="item" v-if="param">
      <label>请求参数：</label>
      <input class="input" type="text" v-model="paramData" />
    </div>

    <div v-if="body || queryParams" class="item">
      <label>请求参数：</label>
      <component
        v-if="codemirrorComponent"
        :is="codemirrorComponent"
        v-model="jsonData"
        :options="cmOptions"
      ></component>
    </div>

    <div class="item">
      <button class="btn" @click="getData()">调用接口</button>
    </div>

    <div class="item" v-if="result.data">
      <div>
        <label>返回结果：</label>
        <a class="btn-clean" @click="cleanResult()">清空结果</a>
      </div>

      <component
        v-if="JsonViewerComponent"
        :is="JsonViewerComponent"
        :style="{ marginTop: '20px', background: '#f7f8fb' }"
        :expand-depth="1"
        :value="result.data"
        :boxed="true"
        :copyable="true"
        :expanded="true"
      >
      </component>
    </div>
  </div>
</template>
<script>
import { createHttpClient } from "../api/index";
import "codemirror/lib/codemirror.css";
import "codemirror/theme/idea.css";
import "codemirror/addon/lint/lint.css";
export default {
  props: {
    title: String,
    link: String,
    methodType: String,
    url: String,
    isToken: Boolean,
    body: Object | Array,
    param: {
      type: String,
      default: "",
    },
    queryParams: Object,
  },
  data() {
    return {
      //接口返回结果展示组件
      JsonViewerComponent: null,
      //请求参数可编辑组件
      codemirrorComponent: null,
      //请求参数可编辑组件配置
      cmOptions: {
        mode: "application/json",
        theme: "idea",
        lineNumbers: true,
        matchBrackets: true,
        autoRefresh: true,
        lineWrapping: true,
        autofocus: true,
        smartIndent: false,
        autocorrect: true,
        spellcheck: true,
        lint: true,
        gutters: ["CodeMirror-lint-markers"],
      },
      //接口前缀
      baseUrl: "",
      //接口头部令牌
      accessToken: "",
      //请求参数（body、queryParams）
      jsonData: "",
      //接口返回结果
      result: {
        status: "",
        data: "",
      },
      //拼接接口的参数，props数据不能直接修改，需存在data转化
      paramData: "",
    };
  },
  mounted() {
    import("../../../node_modules/codemirror/mode/javascript/javascript");
    import("../../../node_modules/codemirror/mode/css/css");
    import("../../../node_modules/codemirror/addon/lint/lint");
    import("../../../node_modules/codemirror/addon/lint/json-lint");
    import("../../../node_modules/codemirror/addon/display/autorefresh");
    import("../../../node_modules/jsonlint").then((module) => {
      window.jsonlint = module;
    });
    import("../../../node_modules/vue-json-viewer").then((module) => {
      this.JsonViewerComponent = module.default;
    });
    import("../../../node_modules/vue-codemirror").then((module) => {
      this.codemirrorComponent = module.default.codemirror;
    });
  },
  created() {
    this.baseUrl = this.$themeConfig.apiBaseUrl;
    this.paramData = this.param;
    const data = this.body || this.queryParams || null;
    this.jsonData = data ? JSON.stringify(data, null, "\t") : "";
  },
  methods: {
    getData() {
      const http = createHttpClient(this.accessToken);
      http
        .request({
          method: this.methodType,
          url: `${this.baseUrl}${this.url}${this.paramData}`,
          data: this.body ? JSON.parse(this.jsonData) : null,
          params: this.queryParams
            ? new URLSearchParams(JSON.parse(this.jsonData))
            : null,
        })
        .then((res) => {
          this.result.data = res;
        })
        .catch((error) => {
          this.result.data = error;
        });
    },
    cleanResult() {
      this.result.data = "";
    },
  },
};
</script>
<style scoped>
.item {
  margin-bottom: 20px;
}
label {
  font-size: 14px;
  font-weight: bold;
}
.btn {
  padding: 8px 12px;
  background: #6373da;
  color: #fff;
  border: 0;
  cursor: pointer;
  border-radius: 3px;
}
.btn:hover {
  opacity: 0.8;
}
.result {
  display: block;
  padding: 30px;
  background: #f7f8fb;
  border-radius: 6px;
  border: 1px solid #b4bec8;
  position: relative;
  margin-bottom: 30px;
}
.btn-clean {
  float: right;
  cursor: pointer;
}
.input {
  border: 1px solid #ddd;
  border-radius: 2px;
  width: 348px;
  padding: 8px 6px;
}
</style>